package jp.sourceforge.akjrcp.ui.param;

import java.util.List;
import java.util.Map;

import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.ui.GenericParameters;
import jp.sourceforge.akjrcp.ui.GenericParametersEditorDialog;
import jp.sourceforge.akjrcp.ui.GenericParametersEventListener;
import jp.sourceforge.akjrcp.ui.GenericParametersFieldEditor;
import jp.sourceforge.akjrcp.ui.GenericParametersOptionList;
import jp.sourceforge.akjrcp.ui.GenericParametersOptionUIEditor;
import jp.sourceforge.akjrcp.ui.GenericParametersSaveDialog;
import jp.sourceforge.akjrcp.ui.GenericParametersTableViewer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.PlatformUI;

public abstract class AbstractGenericParamViewComposite extends Composite{
	
	public static Log log=LogFactory.getLog(AbstractGenericParamViewComposite.class);
	public static final String SELECTION_INDEX="settings_selection_index";
	public static final String SETTINGS="settings_data";
	
	
	protected GenericParametersTableViewer tableViewer;
	protected GenericParametersOptionList editor;
	
	protected Button saveSetting;
	protected Button newSetting;
	
	private String preferenceKey;
	
	private IPreferenceStore preferenceStore;
		
	private boolean rightClicked;
	private Button editSetting;

	private int lastSelection;
	public AbstractGenericParamViewComposite(Composite parent, int style,String key) {
		super(parent, style);
		this.preferenceKey=key;
		//
		
	}

	public class SelectChanged implements ISelectionChangedListener{

		public void selectionChanged(SelectionChangedEvent event) {
			//was trying avoid right click,but faild,table auto selected.
			if(!rightClicked){
			tableSelectionChanged();
			}
		}
		
	}
	

	public GenericParameters getSelectionItem(){
		int index=tableViewer.getTable().getSelectionIndex();
		if(index==-1){
			index=0;//-1 means no selection and default this select.
		}
		if(index>=0 && index<tableViewer.getTable().getItemCount()){
		return (GenericParameters) tableViewer.getTable().getItem(index).getData();
		}else{
			log.warn("index outbound:"+index);
			return null;
		}
	}
	
	public void setSelectionItem(String label){
		log.info("selectItem:"+label);
		int size=tableViewer.getTable().getItemCount();
		for(int i=0;i<size;i++){
		
			GenericParameters parameters=(GenericParameters) tableViewer.getTable().getItem(i).getData();
			if(parameters.getName().equals(label)){
				log.info("call select change:"+label);
				tableViewer.getTable().setSelection(i);
				return;
			}
		}
	}
	public void tableSelectionChanged(){
		GenericParameters parameters;
		saveSetting.setEnabled(false);//changed
		int selection=tableViewer.getTable().getSelectionIndex();
		if(selection>=0){
		log.info("table item changed:"+selection);
		parameters=(GenericParameters) tableViewer.getTable().getItem(tableViewer.getTable().getSelectionIndex()).getData();
		//log.info("size:"+paramList.size());
		}else{
			//setDefault
			parameters=makeDefaultGenericParameters();
		}
		if(parameters==null){
			log.warn("maybe makeDefault broken");
		}
		Map map=parameters.getParameters();
		
		editor.setParameters(map);
		saveSetting.setEnabled(false);//changed
		
	selectionChanged();//call some event
	}
	
	/*
	 * for some event
	 */
	public void selectionChanged(){};
	
	/*
	 * for new settings
	 */
	public abstract GenericParameters makeDefaultGenericParameters(); 


	/*
	 * new is return makeDefaultGenericParameters.
	 * so not effect current settings.use save
	 */
	public class GenericNew implements SelectionListener {

		public void widgetDefaultSelected(SelectionEvent e) {
			
		}

		public void widgetSelected(SelectionEvent e) {
			GenericParametersEditorDialog dialog=new GenericParametersEditorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
			
			int result=dialog.open();
			if(result==Dialog.OK){
				GenericParameters newed=makeDefaultGenericParameters();
				newed.setName(dialog.getName());
				newed.setComment(dialog.getComment());
				
				//setDefault parameter
				tableViewer.getGenericParameters().add(newed);
				tableViewer.refresh();
				
				//save
				doSave();
				
				tableViewer.getTable().setSelection(tableViewer.getTable().getItemCount()-1);//select last one.
				tableSelectionChanged();//update items
			}else{
				log.info(result);
			}
		}
	}
	
	public class GenericEdit implements SelectionListener {
		int dialogWidth=480;
		int dialogHeight=480;
		public void widgetDefaultSelected(SelectionEvent e) {
			
		}

		public void widgetSelected(SelectionEvent e) {
			
			int index=tableViewer.getTable().getSelectionIndex();
			if(index==-1){
				return;
			}
			GenericParameters setting=(GenericParameters) tableViewer.getGenericParameters().get(index);
			
			log.trace(setting.mapToCsv(editor.getParameters()));
			//String command=GenericParameters.getCSVHeaderParamRemovedLine(GenericParameters.parametersToCsv(setting));
			//log.info("command:"+command);
			GenericParametersEditorDialog dialog=new GenericParametersEditorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
			dialog.setName(setting.getName());
			dialog.setComment(setting.getComment());
			Map newMap=editor.getParameters();
			dialog.setParameters(newMap);
			//dialog.setCommand(command);
			//GenericParametersOptionUIEditor optionEditor=null;

			
		
		
			dialog.setDialogWidth(dialogWidth);
			dialog.setDialogHeight(dialogHeight);
			int result=dialog.open();
			
			if(result==Dialog.OK){
				lastSelection=index;
				//tableViewer.refresh();
				
				//use same
				log.warn("maybe dont work");
				//GenericParameters edited=GenericParameters.csvToParameters(dialog.getCommand());
				//setting.setParameters(edited.getParameters());
	
				//must parameter first,otherwise name and comment 'll removed
				filterSaveParameters(newMap);
				setting.setParameters(newMap);
				
				setting.setName(dialog.getName());
				setting.setComment(dialog.getComment());
				

				
				//save
				doSave();
			
				//tableViewer.getTable().setSelection(index);
				//tableSelectionChanged();
			}else{
				log.info(result);
			}
			
		}
	}
	
	protected void doSave(){
		//save
		GenericParameters infos[] = (GenericParameters[]) tableViewer.getGenericParameters().toArray(new GenericParameters[0]);
		String newValue=GenericParametersFieldEditor.toStoreString(infos);
		getPreferenceStore().setValue(getPreferenceKey()+"."+SETTINGS,newValue);
	}

	
	
	public class GenericSave implements SelectionListener {

		public void widgetDefaultSelected(SelectionEvent e) {
			
		}

		public void widgetSelected(SelectionEvent e) {
		GenericParameters parameter=tableViewer.getCurrentSelection();
		GenericParametersSaveDialog dialog=new GenericParametersSaveDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
		String oldName=parameter.getName();
		if(parameter==null){
		dialog.setName(Messages.getString("dropsomething.newsetting"));	
		}else{
		String newName=tableViewer.copiedName(parameter);
		dialog.setName(newName);
		dialog.setComment(parameter.getComment());
		}
		
		int ret=dialog.open();
		int selection;
		if(ret==Dialog.OK){
			log.info("Save:"+dialog.isSaveOverwrite());
			Map<String ,String> newMap=editor.getParameters();
			filterSaveParameters(newMap);
			if(dialog.isSaveOverwrite()){
//				overwrite or copy
				parameter.setParameters(newMap);
				parameter.setName(oldName);//re set old name.
				parameter.setComment(dialog.getComment());
				selection=tableViewer.getTable().getSelectionIndex();
			}else{
				GenericParameters newParam=new GenericParameters(newMap);
				newParam.setName(dialog.getName());
				newParam.setComment(dialog.getComment());
				
				tableViewer.getGenericParameters().add(newParam);
				tableViewer.refresh();//
				selection=tableViewer.getTable().getItemCount()-1;//added item.
			}
			//store data
			
			GenericParameters infos[] = (GenericParameters[]) tableViewer.getGenericParameters().toArray(new GenericParameters[0]);
			//String oldValue=getPreferenceStore().getString(H264SettingPage.EXPORT_H264_SETTINGS);
			String newValue=GenericParametersFieldEditor.toStoreString(infos);
			//set only difference
			
//			save store
			log.info("saved:"+getPreferenceKey()+"."+SETTINGS+","+newValue);
			if(getPreferenceStore()!=null){
			getPreferenceStore().setValue(getPreferenceKey()+"."+SETTINGS,newValue);
			}
			
			tableViewer.getTable().setSelection(selection);
			tableSelectionChanged();
			//update value;
		}
		}

	}
	//default nothing do
	protected void filterSaveParameters(Map<String ,String> map){
		
	}
	
	public class StoreSelect implements ISelectionChangedListener{

		public void selectionChanged(SelectionChangedEvent event) {
			log.trace("selection Index Changed:"+getPreferenceKey()+"."+SELECTION_INDEX);
			if(getPreferenceStore()!=null){
			getPreferenceStore().setValue(getPreferenceKey()+"."+SELECTION_INDEX, tableViewer.getTable().getSelectionIndex());
			}
			}
		
	}
	

	

	

	
	public void selectCombo(CCombo combo,String value){
		int s=combo.getItemCount();
		for (int i = 0; i <s; i++) {
			if(combo.getItem(i).equals(value)){
				combo.select(i);
				break;
			}
		}
	}
	


	

	
	
	public String toTime(long bps,long maxMega){
		long bytes=bps/8;
		
		long second=maxMega*1024*1024/bytes;
		long hour=second/3600;
		second=second%3600;
		long min=second/60;
		long sec=second%60;
		
		String hstring=""+hour;
		if(hstring.length()<2){
			hstring="0"+hstring;
		}
		
		String mstring=""+min;
		if(mstring.length()<2){
			mstring="0"+mstring;
		}
		
		String sstring=""+sec;
		if(sstring.length()<2){
			sstring="0"+sstring;
		}
		return hstring+":"+mstring+":"+sstring;
	}

	
	
	
	public void updateSettingTable(){
		List list=GenericParametersTableViewer.loadList(getPreferenceStore().getString(getPreferenceKey()+"."+SETTINGS));
		

		//warn aly selection clear when value setted.
		tableViewer.setGenericParametersList(list);
		
		
		
				if(tableViewer.getTable().getItemCount()>0){
					//now lastselection setted only edit
					if(lastSelection>=0 && lastSelection<tableViewer.getTable().getItemCount()){
					tableViewer.getTable().setSelection(lastSelection);	
					}else{//invalid last selection
					tableViewer.getTable().setSelection(0);
					}
					tableSelectionChanged();
					}
	}
	public class PreferenceStoreMonitor implements IPropertyChangeListener {

		public void propertyChange(PropertyChangeEvent event) {
			log.trace(event.getProperty());
			if (event.getProperty().equals(getPreferenceKey()+"."+SETTINGS)) {
				updateSettingTable();
			}
		}
	}
	



	

	


	
	public boolean setFocus(){
		return tableViewer.getTable().setFocus();
	}

public void createControls(GenericParametersOptionList editor) {
			this.editor=editor;
			this.setLayout(new FillLayout());
			Composite composite=new Composite(this,SWT.NULL);
			GridLayout rootLayout=new GridLayout(1,true);
			rootLayout.marginHeight=3;
			rootLayout.marginWidth=5;
			
			composite.setLayout(rootLayout);
			
			Composite listComposite=new Composite(composite,SWT.NULL);
			GridData listData=new GridData(GridData.FILL_BOTH);
			
			listComposite.setLayoutData(listData);
			GridLayout listLayout=new GridLayout(2,false);
			listLayout.marginHeight=0;
			listLayout.marginWidth=0;
			listComposite.setLayout(listLayout);
			
			log.info("load:"+getPreferenceKey()+"."+SETTINGS);
			
			//only if preferenceStore not null auto load setting;
			if(getPreferenceStore()!=null){
			List list=GenericParametersTableViewer.loadList(getPreferenceStore().getString(getPreferenceKey()+"."+SETTINGS));
			
			GridData gd = new GridData(GridData.FILL_BOTH);
			//gd.minimumHeight=40;
			gd.widthHint=180;
			gd.heightHint=200;
			//gd.grabExcessVerticalSpace=true;
			tableViewer = new GenericParametersTableViewer(listComposite);
			tableViewer.getTable().setLayoutData(gd);
			tableViewer.setGenericParametersList(list);
			
			
			Menu menu=tableViewer.getPopUpMenu();
			MenuItem delete=new MenuItem(menu,SWT.PUSH);
			delete.setText(jp.sourceforge.akjrcp.ui.Messages.getString("delete"));
			delete.addSelectionListener(new SelectionListener(){

				@Override
				public void widgetDefaultSelected(SelectionEvent e) {
					
				}

				@Override
				public void widgetSelected(SelectionEvent e) {
					int index=tableViewer.getTable().getSelectionIndex();
					if(index>=0){//selected
					//TODO confirm dialog	
					GenericParameters setting=(GenericParameters) tableViewer.getGenericParameters().get(index);
					tableViewer.getGenericParameters().remove(setting);
					tableViewer.refresh();
					log.info("deleted:"+index);
					doSave();
					}
				}});
			}
			
			//trying avoid right click ,but faild
			/*
			tableViewer.getTable().addMouseListener(new MouseListener(){
				@Override
				public void mouseDoubleClick(MouseEvent e) {
					
				}

				@Override
				public void mouseDown(MouseEvent e) {
					
					if(e.button==3){//Right button
						rightClicked=true;
					}else{
						rightClicked=false;
					}
				}

				@Override
				public void mouseUp(MouseEvent e) {
					rightClicked=false;
				}});
			*/
			tableViewer.addSelectionChangedListener(new SelectChanged());
			
			
			Composite buttons=new Composite(listComposite,SWT.NULL);
			buttons.setLayout(new GridLayout(1,false));
			
			
			newSetting = new Button(buttons,SWT.NULL);
			newSetting.setText(Messages.getString("h264converter.new"));
			newSetting.addSelectionListener(new GenericNew());
			
			
			saveSetting = new Button(buttons,SWT.NULL);
			saveSetting.setText(Messages.getString("h264converter.save"));
			saveSetting.setEnabled(false);
			saveSetting.addSelectionListener(new GenericSave());
			
			//buttonList=new ArrayList();
			//settingList=new ArrayList();
			editSetting = new Button(buttons,SWT.NULL);
			editSetting.setText(Messages.getString("h264converter.edit"));
			
			editSetting.addSelectionListener(new GenericEdit());
			
			
			
			
			editor.addListener(new GenericParametersEventListener(){
				public void updateModified(boolean modified) {
					saveSetting.setEnabled(modified);
				}
				
			});
			//updateStatus();
			
			
			if(getPreferenceStore()!=null){
			getPreferenceStore().addPropertyChangeListener( new PreferenceStoreMonitor());
			
			//load selection index
			int defaultSelect=getPreferenceStore().getInt(getPreferenceKey()+"."+SELECTION_INDEX);
			log.info("defaultSelect:"+defaultSelect+","+getPreferenceKey()+"."+SELECTION_INDEX);
			if(tableViewer.getTable().getItemCount()>defaultSelect){
				//if defaultSelect minus call 0
				tableViewer.getTable().setSelection(Math.max(0,defaultSelect));//this method don't call SelectionChangedListener 
				
				}else{
					if(tableViewer.getTable().getItemCount()>0){
						tableViewer.getTable().setSelection(0);//this method don't call SelectionChangedListener 
					}else{
						log.info("item is empty");
					}
				}
			}
			tableSelectionChanged();
			tableViewer.addSelectionChangedListener(new StoreSelect());
			
		}


	
		public Object getControler() {
			return this;
		}
		
	
	

	



	public String getPreferenceKey() {
		return preferenceKey;
	}

	public void setPreferenceKey(String preferenceKey) {
		this.preferenceKey = preferenceKey;
	}

	public IPreferenceStore getPreferenceStore() {
		return preferenceStore;
	}

	public void setPreferenceStore(IPreferenceStore preferenceStore) {
		this.preferenceStore = preferenceStore;
	}
	
	

}
